﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JingQiao.Ads.Infrastructure.Data.EF.Repository
{
    using Domain.Model;
    using Domain.Model.DomainObject;
    using Domain.Model.Repository;

    public class DestinationRepository : BaseRepository<IDestination>, IDestinationRepository
    {
        public DestinationRepository(IContext context)
            : base(context)
        {
        }

        public override void Add(IDestination entity)
        {
            base.Add(entity);
        }

        public bool IsHasAdvertisement(int destId)
        {
            return this._context.DestPositionAd.Any(x => x.DestinationId == destId);
        }

        public IDestination FindById(int id)
        {
            Check.Argument.IsNotNegativeOrZero(id, "id");

            return this._context.Destination.Include("ConfigInfo").FirstOrDefault(d => d.DestinationId == id);
        }

        public IDestination FindBySiteName(string siteName)
        {
            Check.Argument.IsNotEmpty(siteName, "siteName");

            return this._context.Destination.Include("ConfigInfo").FirstOrDefault(d => d.SiteName == siteName);
        }

        public IDestination FindDefaultByConfigId(int configinfoId)
        {
            Check.Argument.IsNotNegativeOrZero(configinfoId, "configinfoId");

            return this._context.Destination.Include("ConfigInfo")
                .FirstOrDefault(d => d.ConfigInfo.ConfigInfoId == configinfoId&&d.IsDefault);
        }

        public IQueryable<IDestination> FindByIds(string destinations)
        {
            Check.Argument.IsNotEmpty(destinations, "destinations");

            return this._context.Destination.Where("it.DestinationId in {" + destinations + "}");
        }

        public IQueryable<IDestination> FindByRegionIds(string regionIds)
        {
            Check.Argument.IsNotEmpty(regionIds, "regionIds");

            return this._context.Destination.Where("it.RegionId in {" + regionIds + "}");
        }

        public PagedResult<IDestination> FindByParentId(int parentId, int pageSize, int pageIndex)
        {
            var count = CountByParentId(parentId);

            var destinations = this._context.Destination.Include("ConfigInfo")
                .Where(x => x.ParentId == parentId)
                .OrderByDescending(x => x.DestinationId)
                .Skip(pageSize * pageIndex)
                .Take(pageSize);

            return BuildPagedResult<IDestination>(destinations, count);
        }

        public int CountByParentId(int parentId)
        {
            return this._context.Destination.Where(x => x.ParentId == parentId).Count();
        }

        public IQueryable<IDestination> FindAll()
        {
            var destinations = this._context.Destination.Include("ConfigInfo")
                .OrderBy(x => x.Sequence);
            return destinations;
        }


        public IQueryable<IDestination> FindByConfigId(int configId)
        {
            var destinations = this._context.Destination.Include("ConfigInfo")
                .Where(x => x.ConfigInfo.ConfigInfoId == configId)
                .OrderByDescending(x => x.DestinationId);
            return destinations;
        }

        public IQueryable<IDestination> FindByConfigIdAndRegionIds(int configId, string regionIds)
        {
            Check.Argument.IsNotEmpty(regionIds, "regionIds");

            var destinations = this._context.Destination.Include("ConfigInfo")
                    .Where("it.RegionId in {" + regionIds + "}")
                    .Where(x => x.ConfigInfo.ConfigInfoId == configId)
                .OrderByDescending(x => x.DestinationId);
            return destinations;
        }

        public int CountByConfigIdAndRegionIds(int configId, string regionIds, string keyWord)
        {
            Check.Argument.IsNotEmpty(regionIds, "regionIds");
            var count = 0;
            if (string.IsNullOrEmpty(keyWord))
            {
                count = this._context.Destination.Include("ConfigInfo")
                    .Where("it.RegionId in {" + regionIds + "}")
                    .Where(x=>x.ConfigInfo.ConfigInfoId==configId)
                    .Count();
            }
            else
            {
                count = this._context.Destination.Include("ConfigInfo")
                    .Where("it.RegionId in {" + regionIds + "}")
                    .Where(x => x.ConfigInfo.ConfigInfoId == configId)
                    .Where(x => x.Name.Contains(keyWord))
                    .Count();
            }
            return count;
        }

        public PagedResult<IDestination> FindByConfigIdAndRegionIds(int configId, string regionIds, string keyWord, int pageSize, int pageIndxe)
        {
            Check.Argument.IsNotNegativeOrZero(pageSize, "pageSize");

            var count = CountByConfigIdAndRegionIds(configId, regionIds, keyWord);
            
            if (string.IsNullOrEmpty(keyWord))
            {
                var dests = this._context.Destination.Include("ConfigInfo")
                    .Where("it.RegionId in {" + regionIds + "}")
                    .Where(x=>x.ConfigInfo.ConfigInfoId==configId)
                    .OrderByDescending(x => x.Sequence).Skip(pageSize * pageIndxe).Take(pageSize);

                return BuildPagedResult<IDestination>(dests, count);
            }
            else
            {
                var dests = this._context.Destination.Include("ConfigInfo")
                    .Where("it.RegionId in {" + regionIds + "}")
                    .Where(x => x.ConfigInfo.ConfigInfoId == configId)
                    .Where(x=>x.Name.Contains(keyWord)&&x.ConfigInfo.ConfigInfoId==configId)
                     .OrderByDescending(t => t.Sequence).Skip(pageSize * pageIndxe).Take(pageSize);

                return BuildPagedResult<IDestination>(dests, count);
            }
        }

        public PagedResult<IDestination> FindByConfigId(int configId, int pageSize, int pageIndex)
        {
            var count = CountByConfigId(configId);

            var destinations = this._context.Destination
                .Where(t => t.ConfigInfo.ConfigInfoId == configId)
                .OrderByDescending(t => t.DestinationId)
                .Skip(pageSize * pageIndex)
                .Take(pageSize);

            return BuildPagedResult<IDestination>(destinations, count);
        }

        public int CountByConfigId(int configId)
        {
            return this._context.Destination.Where(d => d.ConfigInfo.ConfigInfoId == configId).Count();
        }
    }
}
